package com.njtoyo.taxi.admin.service.data.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njtoyo.taxi.admin.mapper.master.entity.*;
import com.njtoyo.taxi.admin.mapper.master.mapper.CouponMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.GeoCantonMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.RideOrderMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.UserMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.data.AllowanceStatisticsMapper;
import com.njtoyo.taxi.admin.rest.presenter.business.driver_withdraw.DriverWithdrawListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.data.allowance.allowance_statistics.HistogramPresenter;
import com.njtoyo.taxi.admin.rest.presenter.data.allowance.allowance_statistics.PieChartPresenter;
import com.njtoyo.taxi.admin.rest.presenter.platfrom.AdminUserIdentityPresenter;
import com.njtoyo.taxi.admin.service.data.AllowanceStatisticsService;
import com.njtoyo.taxi.entity.backend.AdminUser;
import com.taxi.entity.common.RestResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class AllowanceStatisticsServiceImpl implements AllowanceStatisticsService {

    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private AllowanceStatisticsMapper allowanceStatisticsMapper;
    @Autowired
    private GeoCantonMapper cantonMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RideOrderMapper rideOrderMapper;

    /**
     * 免佣卡-饼图数据查询
     *
     * @return
     */
    @Override
    public RestResult pieChartData(Integer type, String startDate, String endDate,AdminUser adminUser) {
        if (StrUtil.isBlank(startDate) || StrUtil.isBlank(endDate)) {
            startDate = DateUtil.beginOfDay(DateUtil.date()).toString();
            endDate = DateUtil.endOfDay(DateUtil.date()).toString();
        } else {
            startDate = DateUtil.beginOfDay(DateUtil.parseDate(startDate)).toString();
            endDate = DateUtil.endOfDay(DateUtil.parseDate(endDate)).toString();
        }
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter)adminUser.getIdentity();
        LambdaQueryWrapper<Coupon> couponLambdaQueryWrapper = Wrappers.<Coupon>lambdaQuery();
        switch (adminUser.getAccountType()) {
            case company:
                couponLambdaQueryWrapper.in(Coupon::getCantonId, identity.getCantonIds());
                break;
            case canton:
                couponLambdaQueryWrapper.in(Coupon::getCantonId, identity.getCantonIds());
                break;
        }
        couponLambdaQueryWrapper.eq(Coupon::getSaleCategory, type)
                .between(Coupon::getCreatedAt, startDate, endDate);
        List<Coupon> coupons = couponMapper.selectList(couponLambdaQueryWrapper);
        List<PieChartPresenter> list = new ArrayList<>();
        if (CollUtil.isNotEmpty(coupons)) {

            List<Coupon> used_true = coupons.stream().filter(x -> x.getHadUsed() == true).collect(Collectors.toList());
            list.add(new PieChartPresenter().setType("已使用").setValue(NumberUtil.mul(NumberUtil.div(used_true.size(), coupons.size(), 2), 100)));
            List<Coupon> used_false = coupons.stream().filter(x -> x.getHadUsed() == false).collect(Collectors.toList());
            list.add(new PieChartPresenter().setType("未使用").setValue(NumberUtil.mul(NumberUtil.div(used_false.size(), coupons.size(), 2), 100)));
            //int used = RandomUtil.randomInt(9);
            //            list.add(new PieChartPresenter().setType("已使用").setValue(NumberUtil.div(used, 10, 2) * 100));
            //            list.add(new PieChartPresenter().setType("未使用").setValue(NumberUtil.div(10 - used, 10, 2) * 100));

        }
        return RestResult.success(list);
    }

    @Override
    public RestResult histogramChartData(Integer type, String startDate, String endDate,AdminUser adminUser) {
        if (StrUtil.isBlank(startDate) || StrUtil.isBlank(endDate)) {
            startDate = DateUtil.beginOfDay(DateUtil.date()).toString();
            endDate = DateUtil.endOfDay(DateUtil.date()).toString();
        } else {
            startDate = DateUtil.beginOfDay(DateUtil.parseDate(startDate)).toString();
            endDate = DateUtil.endOfDay(DateUtil.parseDate(endDate)).toString();
        }
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter)adminUser.getIdentity();
        LambdaQueryWrapper<Coupon> couponLambdaQueryWrapper = Wrappers.<Coupon>lambdaQuery();
        switch (adminUser.getAccountType()) {
            case company:
                couponLambdaQueryWrapper.in(Coupon::getCantonId, identity.getCantonIds());
                break;
            case canton:
                couponLambdaQueryWrapper.in(Coupon::getCantonId, identity.getCantonIds());
                break;
        }
        couponLambdaQueryWrapper.eq(Coupon::getSaleCategory, type)
                .between(Coupon::getCreatedAt, startDate, endDate);
        List<HistogramPresenter> list = new ArrayList<>();
        List<Coupon> coupons = couponMapper.selectList(couponLambdaQueryWrapper);
        if (CollUtil.isNotEmpty(coupons)) {
            List<Long> cantonIds = coupons.stream().map(Coupon::getCantonId).distinct().collect(Collectors.toList());
            Map<Long, List<Coupon>> toMaps = coupons.stream().collect(Collectors.groupingBy(Coupon::getCantonId));
            for (Long cantonId : cantonIds) {
                GeoCanton geoCanton = cantonMapper.selectById(cantonId);
                if (ObjectUtil.isNotNull(geoCanton)) {
                    List<Coupon> coupons_list = toMaps.get(cantonId);
                    int num = coupons_list.size();
                    Double amount = coupons_list.stream().map(Coupon::getDiscountDigit).reduce(Double::sum).get();
                    list.add(new HistogramPresenter().setName("张数").setType(geoCanton.getName()).setValue(num));
                    list.add(new HistogramPresenter().setName("价值(元)").setType(geoCanton.getName()).setValue(amount));
                }
            }
        }
        return RestResult.success(list);
    }

    @Override
    public RestResult getFreeCommissionPage(Integer type, Long current, Long size, String startDate, String endDate, AdminUser adminUser) {
        if (StrUtil.isBlank(startDate) || StrUtil.isBlank(endDate)) {
            startDate = DateUtil.beginOfDay(DateUtil.date()).toString();
            endDate = DateUtil.endOfDay(DateUtil.date()).toString();
        } else {
            startDate = DateUtil.beginOfDay(DateUtil.parseDate(startDate)).toString();
            endDate = DateUtil.endOfDay(DateUtil.parseDate(endDate)).toString();
        }
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter)adminUser.getIdentity();
        LambdaQueryWrapper<Coupon> couponLambdaQueryWrapper = new LambdaQueryWrapper<>();
        switch (adminUser.getAccountType()) {
            case company:
                couponLambdaQueryWrapper.in(Coupon::getCantonId, identity.getCantonIds());
                break;
            case canton:
                couponLambdaQueryWrapper.in(Coupon::getCantonId, identity.getCantonIds());
                break;
        }
        Page<Coupon> page = new Page<>(current, size);
        couponLambdaQueryWrapper.eq(Coupon::getSaleCategory, type)
                .between(Coupon::getCreatedAt, startDate, endDate)
                .orderByDesc(Coupon::getCreatedAt);
        Page<Coupon> couponPage = couponMapper.selectPage(page, couponLambdaQueryWrapper);
        List<Dict> result = new ArrayList<>();
        for (Coupon coupon : couponPage.getRecords()) {
            Dict dict = new Dict();
            dict.set("id", coupon.getId());
            dict.set("createdAt", coupon.getCreatedAt());
            User user = userMapper.selectById(coupon.getUserId());
            if (ObjectUtil.isNotNull(user)) {
                dict.set("userId", user.getId());
                dict.set("userPhone", user.getMobileNumber());
            }
            if (coupon.getHadUsed()) {
                List<RideOrder> rideOrders = rideOrderMapper.selectList(Wrappers.<RideOrder>lambdaQuery().eq(RideOrder::getCouponId, coupon.getId()));
                dict.set("orderId", rideOrders.get(0).getId());
            }
            result.add(dict);
        }
        Map<String, Object> pageResult = new HashMap<>();
        pageResult.put("records", result);
        pageResult.put("total", page.getTotal());
        pageResult.put("size", size);
        pageResult.put("current", current);
        return RestResult.success(pageResult);
    }


}
